RoR_chapter1 オブジェクトの理解
RoR_chapter1 オブジェクトの理解
断片的には理解しているので、基礎は流し読みで進める。
Rubyでいうオブジェクト
文字列などが入った要素のことを指す
変数は、オブジェクトを入れた値のこと
irbで適当な動作確認ができる。 rubyが入っているなら、これを打つだけで起動する
クラス
オブジェクトの型のこと。
code:rb
irb(main):006:0> '指名'.class
=> String
オブジェクトid
オブジェクトの持つ、固有の番号のこと。'氏名'.object_idで確認できる
クラスとインスタンス
オブジェクトxのクラスがAなら、xはAのインスタンスである
氏名はStringのインスタンスであり、1はIntegerのインスタンスである
Stringクラスに属しているなら文字列を出力する.lengthが使えるなど、クラスのイメージは一緒
'氏名'.string // 2
変数に格納する
code:rb
irb(main):016:0> label = '氏名'
=> "氏名"
irb(main):018:0> label.class
=> String
irb(main):019:0> label.length
=> 2
railsのコメントアウトは、#を使う
オブジェクトの仕事
なんらかの振る舞いをすること
インスタンスメソッドを、クラスに定義しよう
phpとこの辺は結局考え方は一緒な気がする
code:rb
class 猫
def 追いかける (ネズミ)
end
end
タマ = 猫.new
クラスを定義して、インスタンス(クラスのオブジェクト)を作ってみる
code:rb
irb(main):001:0> require './user.rb'
=> true
irb(main):002:0> user = User.new
irb(main):003:0> user.class
=> User
クラスとメソッドの定義
code:rb
class User
def name
return "匿名くん" # return有りの書き方
# returnなしでも、以下の記述だけで返り値を出せる
# "匿名くん"
end
end
irb(main):007:0> load './user.rb'
=> true
irb(main):008:0> user = User.new
irb(main):009:0> user.name
=> "匿名くん"
インスタンス変数
@のついた変数のこと
code:rb
class User
# 引数で受け取ったデータをインスタンス変数に格納するメソッド(セッター)
# phpで言うgetName()とか一緒
def name=(name)
@name = name
end
def name
@name
end
end
irb(main):012:0> user = User.new
irb(main):013:0> user.name = 'skonishi'
=> "skonishi"
属性Attribute
オブジェクトの抱えるデータのこと。
↑で言うと、nameはuserの属性であると言える
rubyでは結構出てくるので、この用語は慣れておこう
ゲッター/セッターの簡単な定義
code:rb
class User
# 上のdef name=(name)... , def name ....の2つを兼ねた書き方
# シンボル(後述)を渡す
attr_accessor :name
# 他にも色々渡せる
attr_accessor :address, :email
end
code:rb
irb(main):021:0> user = User2.new
irb(main):022:0> user.email = 'test@gmail.com'
irb(main):023:0> user.address = '112-3344'
irb(main):024:0> user
メソッドからメソッドを使う
code:rb
# これをクラスに追記
def profile
"#{name} (#{address})"
end
irb(main):030:0> user.profile
=> "田中太郎 (112-3344)"
profileメソッドから、nameメソッドとaddressメソッドを使うことができた
nameとaddressもゲッター、セッターというメソッドとして考えるので、「メソッド」という言葉を使う
まとめ
クラス(設計図)からオブジェクトが使われ、その中にインスタンス変数、メソッドが存在する
chapter1-3 演算子
この辺は流し読む。空っぽの状態はnilと示す。
条件分岐
ifは、if - endで示す。
code:rb
# 他
if num == 1 ...
elsif num == 2 ...
else ...
end
unless(そうでなかったら)を示すものも使える
後置if
code:rb
# 条件成立した時に出してほしいものの、後ろにifを書く
puts 'おはよう' if time = '8:00'
配列と処理
each do ||でforeachを書ける
code:php
a.each do |element|
puts element
end
# forも使える
for element in a
puts element
end
ハッシュとシンボル
ハッシュ
内部的にデータとキーを対応づけて格納しておくデータ構造のこと
連想配列みたいなもん
キーにはシンボルという:で始まる識別子が使われることが多い。
シンボル
Symbolクラスのオブジェクト
何かしらの名前を表す存在であること
組み合わせよう
code:rb
options = { font_size: 100, color: 'red' }
いろいろな書き方がある
code:rb
{ "font_size" => 100, ...
{ "font_size": 100,
{ :font_size => 100,
{ font_size: 100, # 一番よく使う
{ 1 => 100, # 数字をキーにする
tizu = {"tokyo": 10}
=> 10
keyとvalueをどちらも取得するには、each doを使う
code:rb
tizu.each do |key, value|
puts key # tokyo
puts value # 10
end
クラスに関する知識
イニシャライズinitialize
__construct()と一緒
クラスがnewで呼ばれた時に実行されるメソッド
インスタンス変数に値を入れたりする時に使う
code:rb
class User
attr_reader :name, :address, :email
def initialize(name, address, email)
@name = name
@address = address
@email = email
end
end
# オブジェクト生成
user = User.new('skoni', '112-3344', 'skoni@gmail.com')
呼び出しに制限をかける
privateメソッドのようなもの
code:rb
class Person
def ...
def ...
private # この行より後に書かれたメソッドは、privateメソッドとなりクラス外から呼べなくなる
def money
@money
end
end
person = Person.new
person.money # エラー
引数にデフォルト値を指定する
code:rb
def name(full = true, with_age = true)
n = if full // fullという引数が存在する(true)ならば
else
given_name
end
// << : n(名前が入っている) に文字を追加する if with_ageがtrueなら.
n << "(#{age})" if with_age
n // return n の省略形
end
person.name
"浦島太郎(25)"
person.name(false, true)
"太郎(25)"
ただし、T/F判定だととても分かりづらい
キーワード引数で指定する
code:rb
def name(full: true, with_age: true)
n = if full
else
given_name
end
n << "#{age}" if with_age
n
end
# キーワード引数で指定することで、何にtrue/falseを入れているの変わりやすくなる
person.name(full: true, with_age: false)
"浦島太郎"
似たクラスを作る(継承)
code:rb
class PriceObject
def total_price
price * Tax.rate
end
def price
# raise: 機能実装がまだであることを表示させるエラー
raise NotImplementedError
end
end
<で表現すればOK
class Product < PricedObject
Productは、PricedObjectの子クラスになる
Railsでよく見かける例
code:rb
# Modelが、Railsの用意した、ApplicationRecordというクラスを継承して作られている例
class Post < ApplicationRecord
...
end
オーバーライドとかも同じ
code:rb
class BaseTask
def puts_message
puts 'BaseTaskのタイトル'
end
end
class Task < BaseTask
def puts_message
# ここに書き込むとオーバーライドできる
# super, と書くことで親メソッドを呼ぶこともできる
super
puts 'Taskのタイトル'
end
end
task = Task.new
puts task.puts_message
# >BaseTaskのタイトル
PHPでいう、parent::work()みたいな感じ
モジュール
一連の振る舞いの設計図を1箇所にまとめた存在のこと。
code:rb
# メソッドを書いていく
module Chatting
def chat
"Hi"
end
end
モジュールからオブジェクトを生成することはできない
クラスに取り込んで使用するのが基本。同じ振る舞いのセットを色んなクラスに追加できる
code:rb
class Dog
include Chatting # モジュールの読み込み
include Calcurate # こういうモジュールがあれば、複数読み込ませることもできる
...
end
pochi = Dog.new
pochi.chat
PHPのトレイトとよく似ているかも
Rubyのクラスメソッド
PHPでいう、Person::hoge()みたいに、public static functionで定義されたメソッド
railsにもある。結構色々なところで使われていたりする
code:rb
class Book < ApplicationRecord
has_many :authors # これも実はクラスメソッド
end
Railsの例外処理
raise
例外を発生させることができるメソッド
code:rb
irb(main):013:0> raise ZeroDivisionError.new('ライズでエラーを投げた')
Traceback (most recent call last):
2: from /Users/skoni/.rbenv/versions/2.5.0/bin/irb:11:in `<main>'
1: from (irb):13
ZeroDivisionError (ライズでエラーを投げた)
PHPのExceptionみたいに、エラークラスがある
基本的にStandardErrorで作れば良い
begin: 例外が発生するかもしれないコードを書く
rescue: 例外に対応するコードを書く
ensure: 例外が発生してもしなくても、実行したいコードを書く
endで締める
code:rb
begin
x = 10
y = 100
puts x
puts y
# 例外を起こす
puts x / 0
rescue StandardError => e
puts "#{e.class}(#{e.message}) エラー発生。"
end
irb(main):013:0> load './exception.rb'
10
100
ZeroDivisionError(divided by 0) エラー発生。 # 起こした箇所でrescueに飛んでいる
Rubyっぽい文法一覧
nilガード||=
number ||= 10
numberもしくは、numberがなかったら取り急ぎ10を入れた値としてのnumberを使うという意味になる
Integerクラスの値が入っていること前提だが、計算するメソッドなどを読んだ時nilだとエラーになる
そういった時に取り急ぎの値を入れられる
ぼっち演算子 &.
レシーバがnilであった場合でもエラーが発生しなくなる
code:rb
class User
def name
'名前'
end
end
user = User.new
user.name # 名前
object = nil
object&.name # nilになる (nameを参照できませんでしたというエラーにならない)
%記法
ソースコードに記述する文字数を減らして可読性をアップさせる
%...で書かれていることが多いので、見かけたらとりあえず検索をかけて何の配列かを調べよう
code:rb
puts array # 配列の中身が出る
array2 = %w(apple banana orange) # 全ての要素が文字列の配列なら、こう書くこともできる
p array2
# シンボルなら、%iで定義できる
symbols = %i(apple, banana, orange)
配列から特定の属性を取り出す
code:rb
user1 = Users.new
user2 = Users.new
user3 = Users.new
ここから、user.nameだけを集めた配列を取得したい
each doの場合
code:rb
names = []
users.each do |user|
names << user.name
end
mapメソッドを使う
配列の各要素に対して、ブロックを実行した結果を格納した配列を返す
code:rb
# 書き方1 各要素(userという名前とした。)に対して、user.nameを出力し、配列に格納
names = users.map do |user|
user.name
end
# 書き方2
names = users.map { |user| user.name }
# 書き方3 usersの各要素の:nameを呼び出して格納していくという意味
# &:は、symbolクラスのto_procというメソッドを呼び出す記法
names = users.map(&:name)